/**
 * 
 */
package signGrammar.expressions.util;

import java.util.Map;

import signGrammar.IShape;
import signGrammar.expressions.CVariable;
import signGrammar.expressions.IGrammarContext;
import signGrammar.expressions.IGrammarExpression;
import signGrammar.util.IBinaryShapeExpression;
import signGrammar.util.IUnaryShapeExpression;
import signGrammar.util.UShapeExpression;

public class CEvaluator implements IGrammarContext {
	
	private IGrammarContext contextDelegate;
	private Map<String, IBinaryExpression> binaryExpressionsEvaluators;
	private Map<String, IUnaryExpression> unaryExpressionsEvaluators;
	
	private Map<String,IBinaryShapeExpression> binaryShapesEvaluators;
	private Map<String,IUnaryShapeExpression> unaryShapesEvaluators;
	
	public CEvaluator(IGrammarContext context) {
		this.contextDelegate = context;
		this.binaryExpressionsEvaluators = UExpression.getBinaryExpressions();
		this.unaryExpressionsEvaluators  = UExpression.getUnaryExpressions();
		
		this.binaryShapesEvaluators = UShapeExpression.getExpressions();
		this.unaryShapesEvaluators  = UShapeExpression.getUnaryExpressions();
	}
	
	public IGrammarExpression eval(String left, String binaryExpressionSign, String right){
		return binaryExpressionsEvaluators.get(binaryExpressionSign)
			.eval( contextDelegate.getVariable(left) , contextDelegate.getVariable(right) );
	}
	public IGrammarExpression eval(IGrammarExpression left, String binaryExpressionSign, String right){
		return binaryExpressionsEvaluators.get(binaryExpressionSign)
			.eval( left.clone() , contextDelegate.getVariable(right) );
	}
	public IGrammarExpression eval(String left, String binaryExpressionSign, IGrammarExpression right){
		return binaryExpressionsEvaluators.get(binaryExpressionSign)
			.eval( contextDelegate.getVariable(left) , right.clone() );
	}	
	public IGrammarExpression eval(String unarySign, String varName){
		return unaryExpressionsEvaluators.get(unarySign)
			.eval( contextDelegate.getVariable(varName) );
	}
	public IGrammarExpression eval(String unarySign, IGrammarExpression expression){
		return unaryExpressionsEvaluators.get(unarySign)
			.eval( expression.clone() );
	}
	public IGrammarExpression eval(String varName){
		return contextDelegate.getVariable(varName);
	}
	
	public IShape evalShape(IShape a, String binaryExpressionSign, IShape b){
		return binaryShapesEvaluators.get(binaryExpressionSign).eval(a, b);
	}
	public IShape evalShape(String unaryExpressionSign, IShape a){
		return unaryShapesEvaluators.get(unaryExpressionSign).eval(a);
	}
	public IShape evalShape(String unaryExpressionSign, String a){
		return unaryShapesEvaluators.get(unaryExpressionSign)
			.eval( contextDelegate.getPrimitives().get(a) );
	}
	public IShape evalShape(String a, String binaryExpressionSign, IShape b){
		return binaryShapesEvaluators.get(binaryExpressionSign)
			.eval(contextDelegate.getPrimitives().get(a), b);
	}
	public IShape evalShape(IShape a, String binaryExpressionSign, String b){
		return binaryShapesEvaluators.get(binaryExpressionSign)
			.eval(a,contextDelegate.getPrimitives().get(b));
	}
	public IShape evalShape(String a, String binaryExpressionSign, String b){
		return binaryShapesEvaluators.get(binaryExpressionSign)
			.eval(contextDelegate.getPrimitives().get(a), contextDelegate.getPrimitives().get(b));
	}
	
	@Override public IGrammarContext assign(String varName, IShape value) {
		return contextDelegate.assign(varName, value);
	}
	@Override public IShape find(String name) {
		return contextDelegate.find(name);
	}
	@Override public CVariable getVariable(String name) {
		return contextDelegate.getVariable(name);
	}
	@Override public Map<String, IShape> getPrimitives() {
		return contextDelegate.getPrimitives();
	}
}